package com.ren.scale.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ren.cache.annotation.MultiCache;
import com.ren.feign.api.recl_user.ReclUserClient;
import com.ren.feign.entity.ReclUserVo;
import com.ren.scale.constant.CachePrefix;
import com.ren.scale.entity.ReclScale;
import com.ren.scale.entity.vo.ReclScaleQueryVo;
import com.ren.scale.entity.vo.ReclScaleVo;
import com.ren.scale.mapper.ReclScaleMapper;
import com.ren.scale.service.ReclScaleCollectionService;
import com.ren.scale.service.ReclScaleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ren.utils.page.PageItem;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author RZY
 * @since 2022-07-13
 */
@Service
public class ReclScaleServiceImpl extends ServiceImpl<ReclScaleMapper, ReclScale> implements ReclScaleService {

    @Autowired
    ReclUserClient userClient;

    @Autowired
    ReclScaleCollectionService scaleCollectionService;

    /**
     *
     * @param id 量表id
     * @return 返回ReclScaleVo量表封装对象
     */
    @Override
    public ReclScaleVo getScaleVoById(Long id) {
        //获取FM对象
        ReclScale reclFm = getScaleById(id);
        //远程feign获取上传用户信息
        ReclUserVo userVo = userClient.getRemoteFmUserInfo(reclFm.getCreateUserId());
        ReclScaleVo reclScaleVo = new ReclScaleVo();
        //封装ReclFmVO
        BeanUtils.copyProperties(userVo, reclScaleVo);
        BeanUtils.copyProperties(reclFm, reclScaleVo);
        return reclScaleVo;
    }

    /**
     * 获取ReclScale的对象
     *
     * @param id 量表id
     * @return 返回ReclScale
     */
    @MultiCache(cacheGroup = "recl_fm",
            prefixKey = CachePrefix.SCALE_ITEM_KEY_PREFIX,
            key = "#id",
            expireTime = 70,
            sync = true)
    private ReclScale getScaleById(Long id) {
        return this.getById(id);
    }

    /**
     *
     * @param reclScaleQueryVo 前台量表分页条件筛选
     * @param current 当前页
     * @param limit 每页记录数
     * @return 返回PageItem封装分页对象
     */
    @Override
    public PageItem<ReclScaleVo> getFrontScaleOfPage(ReclScaleQueryVo reclScaleQueryVo, long current, long limit) {
        //创建分页对象
        Page<ReclScale> scalePage = new Page<>();
        //获取筛选参数
        Long createUserId = reclScaleQueryVo.getCreateUserId();
        Long classifyId = reclScaleQueryVo.getClassifyId();
        Long classifyParentId = reclScaleQueryVo.getClassifyParentId();

        QueryWrapper<ReclScale> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");
        wrapper.eq("status", "verify");

        if(!StringUtils.isEmpty(createUserId)) wrapper.like("create_user_id", createUserId);

        if(!StringUtils.isEmpty(classifyId)) wrapper.eq("classify_id", classifyId);

        if(!StringUtils.isEmpty(classifyParentId)) wrapper.eq("classify_parent_id", classifyParentId);

        //查询分页page
        this.page(scalePage, wrapper);

        List<ReclScale> records = scalePage.getRecords();

        long total = scalePage.getTotal();

        return getPageItem(records, total);
    }

    /**
     *
     * @param reclScaleQueryVo 后台量表分页条件筛选
     * @param current 当前页
     * @param limit 每页记录数
     * @return 返回PageItem封装分页对象
     */
    @Override
    public PageItem<ReclScaleVo> getScaleOfPage(ReclScaleQueryVo reclScaleQueryVo, long current, long limit) {
        //创建分页对象
        Page<ReclScale> scalePage = new Page<>();
        //获取筛选参数
        String scaleTitle = reclScaleQueryVo.getTitle();
        Long createUserId = reclScaleQueryVo.getCreateUserId();
        Long classifyId = reclScaleQueryVo.getClassifyId();
        Long classifyParentId = reclScaleQueryVo.getClassifyParentId();
        String status = reclScaleQueryVo.getStatus();
        Integer scaleCategory = reclScaleQueryVo.getScaleCategory();
        String start = reclScaleQueryVo.getStart();
        String end = reclScaleQueryVo.getEnd();

        QueryWrapper<ReclScale> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");

        if(!StringUtils.isEmpty(scaleTitle)) wrapper.like("scale_title", scaleTitle);

        if(!StringUtils.isEmpty(createUserId)) wrapper.like("create_user_id", createUserId);

        if(!StringUtils.isEmpty(classifyId)) wrapper.eq("classify_id", classifyId);

        if(!StringUtils.isEmpty(classifyParentId)) wrapper.eq("classify_parent_id", classifyParentId);

        if(!StringUtils.isEmpty(scaleCategory)) wrapper.eq("scale_category", scaleCategory);

        if(!StringUtils.isEmpty(start)) wrapper.ge("gmt_create", start);

        if(!StringUtils.isEmpty(end)) wrapper.le("gmt_modified", end);

        if(!StringUtils.isEmpty(status)) wrapper.eq("status", status);
        //查询分页page
        this.page(scalePage, wrapper);

        List<ReclScale> records = scalePage.getRecords();

        long total = scalePage.getTotal();

        return getPageItem(records, total);
    }

    /**
     *
     * @param reclScale 需要更新的ReclScale
     * @return 返回更新结果
     */
    @Override
    public boolean updateScaleById(ReclScale reclScale) {
        return this.updateById(reclScale);
    }

    /**
     *
     * @param id 需要删除的量表id
     * @return 返回删除结果
     */
    @Override
    public boolean delScaleById(Long id) {
        return this.removeById(id);
    }

    /**
     *
     * @param reclScale 需要添加的ReclScale
     * @return 返回添加结果
     */
    @Override
    public boolean addScale(ReclScale reclScale) {
        return this.saveOrUpdate(reclScale);
    }

    public PageItem<ReclScaleVo> getPageItem(List<ReclScale> records, long total) {
        //封装ReclScaleVo集合
        List<ReclScaleVo> reclScaleVos = new ArrayList<>();
        //当没有记录时，直接返回默认PageItem
        if(records.isEmpty()) return new PageItem<ReclScaleVo>().setPageRecords(reclScaleVos)
                .setTotal(0);

        //利用stream流获取records中的上传用户id
        List<Long> userIds = records.stream().map(ReclScale::getCreateUserId).collect(Collectors.toList());
        //远程调用feign接口批量擦查询用户信息
        List<ReclUserVo> userVos = userClient.getRemoteFmUsersInfo(userIds);

        for(int i = 0; i < records.size(); i++) {
            ReclScaleVo reclFmVo = new ReclScaleVo();
            BeanUtils.copyProperties(userVos.get(i), reclFmVo);
            BeanUtils.copyProperties(records.get(i), reclFmVo);
            reclScaleVos.add(reclFmVo);
        }
        //封装分页对象pageItem
        return new PageItem<ReclScaleVo>().setPageRecords(reclScaleVos)
                .setTotal(total);
    }

    @Override
    public List<ReclScaleVo> getFmVos(List<Long> userIds, List<ReclScale> reclScales) {
        //封装ReclScaleVo集合
        List<ReclScaleVo> reclScaleVos = new ArrayList<>();
        //远程调用feign接口批量擦查询用户信息
        List<ReclUserVo> userVos = userClient.getRemoteFmUsersInfo(userIds);

        for(int i = 0; i < reclScales.size(); i++) {
            ReclScaleVo reclScaleVo = new ReclScaleVo();
            BeanUtils.copyProperties(userVos.get(i), reclScaleVo);
            BeanUtils.copyProperties(reclScales.get(i), reclScaleVo);
            reclScaleVos.add(reclScaleVo);
        }
        return reclScaleVos;
    }

    /**
     * @param userId 用户id
     * @return 返回用户收藏的reclScale
     */
    @Override
    public List<ReclScaleVo> getScaleByCollectionUserId(String userId) {
        List<ReclScale> reclFms = this.baseMapper.getScaleByCollectionUserId(userId);
        //获取上传用户的id
        List<Long> userIds = reclFms.stream().map(ReclScale::getCreateUserId).collect(Collectors.toList());
        //openFeign远程调用并封装ReclFmVos
        return getFmVos(userIds, reclFms);
    }

    /**
     *
     * @param id 量表id
     * @return 封装量表订单信息
     */
    @Override
    public ReclScale getScaleOfOrder(Long id) {
        return this.getOne(new QueryWrapper<ReclScale>()
                .select("scale_price", "scale_cover", "description", "title")
                .eq("id", id));
    }
}
